package ch.bfh.fbi.mobicomp.zap09;

import java.util.concurrent.TimeUnit;

import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import ch.quantasy.android.repetitive.service.implementation.ARepetitiveService;
import ch.quantasy.android.speech.SpeechService;
import ch.quantasy.android.speech.string.FrenchString;
import ch.quantasy.android.speech.string.GermanString;
import ch.quantasy.android.speech.string.UKString;

/**
 * Zap08 does allow the CPU to go to deep sleep. However, if the repetition is
 * at about 1 second or even faster, using the AlarmManager is an overkill.
 * 
 * Zap09 uses the ARepetitiveService, which allows to concentrate again on the
 * main algorithm, instead of having to consider all the possibilities within
 * Android to save energy. As one can see, the complexity of the code within
 * Zap09Service drops to a minimum. Great.
 * 
 * Happy working with the ARepetitiveService.
 * 
 * @author quantasy
 * 
 */
public class Zap09Service extends ARepetitiveService {
	public static final String TAG = "ZAP09";
	public static final String REMOTE_ZAPPER_ACTION = "ch.bfh.fbi.mobicomp.zap09.Zap09Service.REMOTE_ZAPPER_ACTION";
	public static final String ZAPPER_KEY_WORD = "ZAP:";
	private static final String destructionKey = "destroyMe";
	private static final String haltKey = "stopDestroyMe";

	private long countdown;
	private final Intent speechIntent;

	public static Intent getZapperIntent(final String message) {
		Intent intent = null;
		if (message.startsWith(Zap09Service.ZAPPER_KEY_WORD)) {
			intent = new Intent(Zap09Service.REMOTE_ZAPPER_ACTION);
			intent.putExtra("message",
					message.substring(Zap09Service.ZAPPER_KEY_WORD.length()));
		}
		return intent;
	}

	public Zap09Service() {
		this.speechIntent = SpeechService.getSpeechIntent();
	}

	@Override
	public int onStartCommand(final Intent intent, final int flags,
			final int startId) {
		Log.d(Zap09Service.TAG, "Service Intent received: " + intent);
		if (intent == null) {
			return super.onStartCommand(intent, flags, startId);
		}
		if (Zap09Service.destructionKey.equals(intent.getExtras().getString(
				"message"))) {
			ARepetitiveService.updateIntentStartStopRepetition(intent, true);
			Log.d(Zap09Service.TAG, "Start");
		} else if (Zap09Service.haltKey.equals(intent.getExtras().getString(
				"message"))) {
			ARepetitiveService.updateIntentStartStopRepetition(intent, false);
			Log.d(Zap09Service.TAG, "stop");
		}

		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onStart(final Intent intent) {
		this.initiateAutoDestruction();
		super.setUpdateInterval(60, TimeUnit.SECONDS);
	}

	@Override
	public void onStop() {
		this.resetAutoDestruction();
	}

	@Override
	public void onRepeat() {
		Log.d(Zap09Service.TAG, "onRepeat");
		this.countDown();
	}

	private void resetAutoDestruction() {
		if (this.countdown == 0) {
			return;
		}
		this.countdown = 0;
		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destruction sequence aborted."), new GermanString(
				"Selbstzerstörungssequenz abgebrochen."), new FrenchString(
				"Séquence d'autodestruction avortée."));
		this.startService(this.speechIntent);

	}

	private void initiateAutoDestruction() {
		if (this.countdown != 0) {
			return;
		}
		this.countdown = System.currentTimeMillis() + (3 * 60 * 1000); // 3
																		// minutes
		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destruction sequence initiated."), new GermanString(
				"Selbstzerstörungs Sequenz eingeleitet."), new FrenchString(
				"Séquence d'autodestruction declanchée."));
		this.startService(this.speechIntent);
	}

	private void countDown() {
		final int timeLeft = (int) ((this.countdown - System
				.currentTimeMillis()) / 1000);
		if (timeLeft > 70) {
			super.setUpdateInterval(60, TimeUnit.SECONDS);
			this.minutesCount(timeLeft);
		} else if (timeLeft > 11) {
			super.setUpdateInterval(10, TimeUnit.SECONDS);
			this.secondsBlockCount(timeLeft);
		} else if (timeLeft > 0) {
			super.setUpdateInterval(1, TimeUnit.SECONDS);
			this.secondsCount(timeLeft);
		} else {
			this.destroy();
		}
	}

	private void minutesCount(final int timeLeft) {
		SpeechService.setPhrase(this.speechIntent, new UKString(""
				+ (1 + (timeLeft / (60))) + "Minutes until self destruction"),
				new GermanString("" + (1 + (timeLeft / (60)))
						+ "Minuten bis zur Selbstzerstörung"),
				new FrenchString("" + (1 + (timeLeft / (60)))
						+ "minutes jusqu'à ce que l'auto-destruction"));
		this.startService(this.speechIntent);
	}

	private void secondsBlockCount(final int timeLeft) {
		if ((timeLeft % 3) == 0) {
			SpeechService.setPhrase(this.speechIntent, new UKString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "Seconds until self destruction"));
		} else if ((timeLeft % 3) == 1) {
			SpeechService.setPhrase(this.speechIntent, new GermanString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "Sekunden bis zur Selbstzerstörung"));
		} else {
			SpeechService.setPhrase(this.speechIntent, new FrenchString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "seconds jusqu'à ce que l'auto-destruction"));
		}
		this.startService(this.speechIntent);
	}

	private void secondsCount(final int timeLeft) {
		SpeechService.setPhrase(this.speechIntent,
				new UKString("" + (timeLeft)));
		this.startService(this.speechIntent);
	}

	private void destroy() {
		this.countdown = 0;
		super.stopTimedRepetition();
		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destroying now."));
		this.startService(this.speechIntent);
	}

	@Override
	public IBinder onBind(final Intent intent) {
		// No Direct Service binding
		return null;
	}

}
